package meiyunting.shiwuzhaoling.service;

import lombok.extern.slf4j.Slf4j;
import meiyunting.shiwuzhaoling.client.LostFoundServiceClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 熔断器演示服务
 * 用于展示熔断器功能
 */
@Slf4j
@Service
public class CircuitBreakerDemoService {

    @Autowired
    private LostFoundServiceClient lostFoundServiceClient;
    
    @Autowired
    private CircuitBreakerService circuitBreakerService;
    
    // 记录调用次数和成功/失败次数
    private final AtomicInteger totalCalls = new AtomicInteger(0);
    private final AtomicInteger successCalls = new AtomicInteger(0);
    private final AtomicInteger failedCalls = new AtomicInteger(0);
    private final AtomicInteger fallbackCalls = new AtomicInteger(0);
    
    // 模拟服务是否可用
    private volatile boolean serviceAvailable = true;
    
    /**
     * 使用熔断器调用实例信息服务
     * @return 实例信息或降级信息
     */
    public Map<String, Object> callInstanceInfoWithCircuitBreaker() {
        totalCalls.incrementAndGet();
        
        return circuitBreakerService.executeWithCircuitBreaker(
                "lostFoundService",
                () -> {
                    // 如果服务不可用，模拟异常
                    if (!serviceAvailable) {
                        failedCalls.incrementAndGet();
                        throw new RuntimeException("服务暂时不可用");
                    }
                    
                    // 正常调用服务
                    Map<String, Object> result = lostFoundServiceClient.getInstanceInfo();
                    successCalls.incrementAndGet();
                    return result;
                },
                () -> {
                    // 降级逻辑
                    fallbackCalls.incrementAndGet();
                    Map<String, Object> fallback = new HashMap<>();
                    fallback.put("port", "降级服务");
                    fallback.put("instanceId", "circuit-breaker-fallback");
                    fallback.put("timestamp", System.currentTimeMillis());
                    fallback.put("status", "fallback");
                    fallback.put("message", "服务暂时不可用，已启用降级");
                    return fallback;
                }
        );
    }
    
    /**
     * 使用熔断器获取用户的失物信息
     * @param userId 用户ID
     * @return 失物列表或降级信息
     */
    public List<Map<String, Object>> getUserLostItemsWithCircuitBreaker(Long userId) {
        totalCalls.incrementAndGet();
        
        return circuitBreakerService.executeWithCircuitBreaker(
                "lostFoundService",
                () -> {
                    // 如果服务不可用，模拟异常
                    if (!serviceAvailable) {
                        failedCalls.incrementAndGet();
                        throw new RuntimeException("服务暂时不可用");
                    }
                    
                    // 正常调用服务
                    List<Map<String, Object>> result = lostFoundServiceClient.getUserLostItems(userId);
                    successCalls.incrementAndGet();
                    return result;
                },
                () -> {
                    // 降级逻辑
                    fallbackCalls.incrementAndGet();
                    return lostFoundServiceClient.getUserLostItems(userId); // 使用Feign客户端的降级实现
                }
        );
    }
    
    /**
     * 切换服务可用状态（用于测试）
     * @return 当前服务状态
     */
    public boolean toggleServiceAvailability() {
        serviceAvailable = !serviceAvailable;
        log.info("服务可用状态已切换为: {}", serviceAvailable);
        return serviceAvailable;
    }
    
    /**
     * 获取服务调用统计信息
     * @return 统计信息
     */
    public Map<String, Object> getStatistics() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalCalls", totalCalls.get());
        stats.put("successCalls", successCalls.get());
        stats.put("failedCalls", failedCalls.get());
        stats.put("fallbackCalls", fallbackCalls.get());
        stats.put("serviceAvailable", serviceAvailable);
        
        // 添加熔断器状态信息
        Map<String, Object> circuitBreakerStatus = circuitBreakerService.getCircuitBreakerStatus("lostFoundService");
        stats.put("circuitBreakerStatus", circuitBreakerStatus);
        
        return stats;
    }
    
    /**
     * 重置统计信息
     */
    public void resetStatistics() {
        totalCalls.set(0);
        successCalls.set(0);
        failedCalls.set(0);
        fallbackCalls.set(0);
        serviceAvailable = true;
        circuitBreakerService.resetCircuitBreaker("lostFoundService");
    }
} 